﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Imaginecup.gameState;

namespace Imaginecup.stateManager
{
    delegate void AddStateEvent(); // 스테이트가 추가될때마다 상태 업데이트

    public class GameStateManager
    {
        private Stack<IGameState> m_GameStateStack; // state관리스택
        private event AddStateEvent m_AddEventArr;

        private Game m_Game;


        public GameStateManager(Game game)
        {
            m_Game = game;
            m_GameStateStack = new Stack<IGameState>();
        }

        private void RemoveState()
        {
            IGameState state = m_GameStateStack.Pop();
            //m_Event(state); // 뺀값을 포함한 Event발생(Stack에서 값을빼고 Update를 하여서 Enable의 상태를 변경하도록함 )

            m_AddEventArr -= state.AddStateEvent; // Event를 뺀다..
            state.RemoveStateEvent();
            m_Game.Components.Remove(state);


        }

        public void PopState()
        {
            if (m_GameStateStack.Count == 0) return;
            RemoveState();
            if (m_GameStateStack.Count > 0)
                m_AddEventArr();
        }
        public void PopAll()
        {
            while (m_GameStateStack.Count > 0)
            {
                RemoveState();
            }
            if (m_GameStateStack.Count > 0)
                m_AddEventArr();
        }

        public void PushState(IGameState state)
        {
            m_AddEventArr += state.AddStateEvent; // Event를 추가한다.

            // m_GameStateList.Add( state );// state를 추가한다.
            m_GameStateStack.Push(state);
            m_Game.Components.Add(state);

            if (m_GameStateStack.Count > 0)
                m_AddEventArr();

        }

        public bool ExsistState(IGameState state) //현재 스택에 존재하는지 여부를 확인한다.
        {

            for (int count = 0; count < m_GameStateStack.Count; count++)
            {

                if (m_GameStateStack.ElementAt(count).Equals(state)) // 같은값이 존재한다.
                {
                    return true;
                }
            }
            return false;
        }

        public IGameState GetTopState()
        {
            if (m_GameStateStack.Count == 0)
                return null;
            return m_GameStateStack.ElementAt(0); // 꼭대기값.
        }

    }
}
